#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2024/10/4 14:18
# @Author  : zy
# @File    : echarts_map.py

import pandas as pd
from pyecharts.charts import BMap
from pyecharts import options as opts
from pyecharts.commons.utils import JsCode
from pyecharts.globals import BMapType


# ['_id','custom', 'name', 'point', 'long', 'lat', 'notice', 'address', 'part','manager', 'tel', 'code']
# 数据
class DfData:
    def __init__(self, df: pd.DataFrame):
        self.__df = df

        self.customs = self.df['custom'].unique().tolist()  # 客户列表
        self.names = [{'custom': custom, 'name_lst': self.make_list_by_custom(custom)} for custom in
                      self.customs]  # 生成器
        self.groups_by_customs = self.df.groupby(by='custom')  # 按客户分组
        self.points = self.df[['point', 'long', 'lat']].values.tolist()  # 位置与经纬度列表

    @property
    def df(self):
        _df = self.__df[
            ['_id', 'point', 'long', 'lat', 'name', 'customID', 'custom', 'part', 'manager', 'tel', 'notice', 'address',
             'code']]
        _df = _df[_df['point'].notnull()]  # 筛选数据去掉未定位的数据
        _df['tel'] = _df['tel'].astype('str')  # 联系方式转为字符串
        _df = _df.fillna('')  # 防止地图标签不显示
        return _df

    @property  # 做数据改变
    def df_1(self):
        _df = self.df
        _df['info'] = _df['part'] + '/' + _df['manager'] + '/' + _df['tel'] + '/' + _df['notice']

        return _df

    def make_dict_by_point(self, point: str) -> dict:
        _df = self.df
        _series = _df[_df['point'] == point]
        _dic = _series.to_dict(orient='records')[0]
        return _dic

    # 根据点名称 返回地图对象需要的数据
    def make_data_pair_by_point_name(self, point_names: list):
        _df = self.df_1[self.df_1['point'].isin(point_names)]  # 筛选数据
        _rs = _df[['point', 'info']]
        return _rs.values.tolist()

    # 根据名称 返回地图对象需要的数据
    def make_data_pair_by_name(self, names: list):
        _df = self.df_1[self.df_1['name'].isin(names)]
        _rs = _df[['point', 'info']]
        return _rs.values.tolist()

    # 根据客户 返回地图对象需要的数据
    def make_data_pair_by_custom(self, customs: list):
        _df = self.df_1[self.df_1['custom'].isin(customs)]
        _rs = _df[['point', 'info']]
        return _rs.values.tolist()

    # 根据客户名称 求区域名称列表
    def make_list_by_custom(self, custom: str):
        df_custom = self.df[self.df['custom'] == custom]  # 按客户名称筛选
        name_lst = df_custom['name'].unique().tolist()
        return name_lst

    # 根据客户名称,区域名称 求点位名称列表
    def make_list_by_custom_and_names(self, custom: str, names: list):
        _df_custom = self.df[self.df['custom'] == custom]  # 按客户名称筛选
        _df_custom_names = _df_custom[_df_custom['name'].isin(names)]  # 按名称筛选
        point_lst = _df_custom_names['point'].unique().tolist()
        return point_lst

    # 根据客户名称 求df
    def make_df_by_custom(self, custom: str):
        _df = self.df
        _df = _df[_df['custom'] == custom]
        _df['point'] = _df['point'] + '-' + _df['code']
        _df = _df[['name', 'point', 'part', 'manager', 'tel', 'address']]
        _ = dict(zip(list(_df.columns), ['区域名称', '点位/编号', '管理部门', '对接人员', '联系电话', '地址']))
        _df = _df.rename(columns=_)
        return _df

    def make_df_by_names(self, custom: str, names: list):
        _df = self.df
        _df = _df[_df['custom'] == custom]
        _df = _df[_df['name'].isin(names)]
        _df['point'] = _df['point'] + '-' + _df['code']
        _df = _df[['point', 'part', 'manager', 'tel', 'address', 'notice']]
        _ = dict(zip(list(_df.columns), ['点位/编号', '管理部门', '对接人员', '联系电话', '地址', '注意事项']))
        _df = _df.rename(columns=_)

        return _df


# 百度地图
class MapCharts:
    AK = r"YuB7ZpekYXLYbkcNU4kJzMe0sIHwYlVz"
    Center = [116.653921, 40.134974]  # 开放大学顺义分校,
    JsCode = """
                function(params) {

                    let name= params.data.name;
                    let value=params.data.value;

                    let arr=value[2].split('/');
                    let a0=arr[0];
                    let a1=arr[1];
                    let a2=arr[2];
                    let a3=arr[3];

                    return `
                        <div>
                            <strong>点位名称：</strong>${name}<br/>
                            <strong>管理单位：</strong>${a0}<br/>
                            <strong>对接人员：</strong>${a1}<br/>
                            <strong>联系电话：</strong>${a2}<br/>
                            <strong>注意事项：</strong>${a3}<br/>
                        </div>
                        `
                }
                """

    def __init__(self, width="800px", height="600px"):
        self.bmap = BMap(
            init_opts=opts.InitOpts(width=width, height=height),
            is_ignore_nonexistent_coord=True  # 忽略不存在的坐标
        )

        self.__add_schema()  # 设置
        self.__set_global_opts()  # 全局设置
        self.__add_control_panel()  # 控制面板

    def __add_schema(self):
        self.bmap.add_schema(
            baidu_ak=self.AK,
            center=self.Center,
            zoom=16,
            is_roam=True,  # 是否开启鼠标缩放和平移漫游。
            map_style=None  # 地图样式配置项
        )

    def __set_global_opts(self):
        self.bmap.set_global_opts(
            # 设置标题
            title_opts=opts.TitleOpts(is_show=True, title='有害垃圾收集点位'),

            # 设置提示
            tooltip_opts=opts.TooltipOpts(
                is_show=True,
                background_color='#FFF0F5',
                border_color='black',
                border_width=1,
                formatter=JsCode(self.JsCode),
                # formatter='{b}<br/>{c0}'
            ),

            # 设置图例
            legend_opts=opts.LegendOpts(
                pos_left='0%',
                pos_top='8%',
                orient='vertical',
                legend_icon='roundRect'
            )
        )

    def __add_control_panel(self):
        self.bmap.add_control_panel(

            # 切换地图类型的控件
            maptype_control_opts=opts.BMapTypeControlOpts(
                position=BMapType.ANCHOR_TOP_RIGHT,
                type_=BMapType.MAPTYPE_CONTROL_HORIZONTAL
            ),

            # 比例尺控件
            scale_control_opts=opts.BMapScaleControlOpts(),

            # 缩略地图控件
            overview_map_opts=opts.BMapOverviewMapControlOpts(is_open=True),

            # 版权控件，您可以在地图上添加自己的版权信息。
            copyright_control_opts=opts.BMapCopyrightTypeOpts(position=3, copyright_='@北京宏鑫汇能'),

            # 地图的平移缩放控件
            # navigation_control_opts=opts.BMapNavigationControlOpts(is_enable_geo_location=True),

            # 地图定位的控件，使用 HTML5 浏览器定位功能
            # geo_location_control_opts=opts.BMapGeoLocationControlOpts(is_enable_auto_location=True),
        )

    def add_points(self, points: list = None):
        if points:
            # 将经纬度数据加入地图对象
            for name, lon, lat in points:
                self.bmap.add_coordinate(name=name, longitude=lon, latitude=lat)
        else:
            tst = [
                ('测试点位1', 116.63705, 40.139883),
                ('测试点位2', 116.63705, 40.140883),
                ('测试点位3', 116.64705, 40.139883),
                ('测试点位4', 116.65705, 40.140883),
            ]
            for name, lon, lat in tst:
                self.bmap.add_coordinate(name=name, longitude=lon, latitude=lat)

        return self

    # 加入数据点，显示在地图上
    def show_points_on_map(self, data_pair: list = None, series_name='', color: str = 'red',
                           symbol_size: int = 30) -> BMap:
        if data_pair:
            self.bmap.add(
                series_name=series_name,
                data_pair=data_pair,
                symbol="pin",
                symbol_size=symbol_size,
                color=color,
                type_='scatter',
                label_opts=opts.LabelOpts(is_show=True, color=color, formatter='{b}', position='right', padding=5),
            )
        else:
            tst = [
                ('测试点位1', 100),
                ('测试点位2', 200),
                ('测试点位3', 300),
                ('测试点位4', 400),
            ]

            self.bmap.add(
                series_name=series_name,
                data_pair=tst,
                symbol="pin",
                symbol_size=symbol_size,
                color=color,
                type_='scatter',
                label_opts=opts.LabelOpts(is_show=True, color=color, formatter='{b}', position='right', padding=5),
            )
        return self.bmap  # 返回地图对象


if __name__ == '__main__':
    source = r"../db/company.xlsx"
    _df = pd.read_excel(source, sheet_name='有害垃圾点位', header=1)
    print(_df.columns)
    dfData = DfData(df=_df)
    print(dfData.df)

    # __data_pair = dfData.make_data_pair_by_point_name(['望泉西里一区', '石景苑', '大龙供热'])
    # __df = dfData.make_df_by_custom("旺泉街道")
    # print(__df)
    # data_pair = dfData.make_data_pair_by_name(['龙泉苑', '牡丹苑社区', '铁十六局社区'])
    # data_pair = dfData.make_data_pair_by_custom(['顺商集团', '旺泉街道'])
    #
    # char = MapCharts()
    # char.add_points(dfData.points)
    # bm = char.show_points_on_map(data_pair=data_pair)
    # #
    # bm.render(r'../tmp/tmp.html')

    ...
